雖然在前面Day1時說是預計照React → TypeScript → AI 協作 → Code Review → 學習回顧 這樣子慢慢進行,但因為個人有時比較善變(?)的關係,決定這一篇臨時直接插入一個讓AI使用React + TypeScript生成的TODO LIST專案,先用「看」的,去看一遍專案裡的程式碼有哪些部份是我可以看懂的,先熟悉一下曾經從未接觸過的寫法。
因為決定是先用看的關係,必定多數是用推斷或猜測的方式去理解每一段程式碼內容,從Day5開始再慢慢深入釐清與分析了解去驗證/修正這些猜測。
第一步我是先從專案結構看起,打開的第一眼沒有看到.vue 檔,而是一堆第一次看到的.tsx
src/
├─ main.tsx ← 我猜這是整個網頁的進入點?
├─ App.tsx ← 應該是主要畫面
├─ App.css ← 樣式
├─ index.css ← 也是樣式(用index的話應該是跟全域有關?)
├─ types.ts ← 以取名來看是應該型別定義?
└─ components/
├─ TodoForm.tsx ← 待辦事項表單
├─ TodoList.tsx ← 整個待辦清單本體
└─ TodoItem.tsx ← 我猜是清單裡的每筆資料?
檔名的部分,像是TodoForm、TodoList、TodoItem 這種命名是完全不陌生,單靠英文單字能猜出應該是「表單」「清單」「單一項目」的分工,跟 Vue 拆元件的邏輯感覺上蠻像是同一套思維。
不過寫 Vue 的時候,一個元件(component)就是一個 .vue 檔,、、 三塊清楚分開放。但我打開App.tsx看時完全沒有 這種東西,畫面的部分跟邏輯的部分好像是混在同一個檔案、同一段程式碼裡面的。
接著稍微看一下檔案內的部分程式碼
程式碼讓我比較不習慣的地方是把 HTML 寫進 JavaScript 裡面:
function App() {
return (
<main>
<h1>Todo List</h1>
<TodoForm />
<TodoList />
</main>
)
}
單看 return 裡面的內容,很像是在寫 HTML;但是它又確實放在一個 JavaScript 函式裡面,而且檔案副檔名還不是.html 或.js,而是.tsx。
目前看下來的猜測是:function App() 是在建立一個叫做 App 的元件。return 裡面放的是這個元件要顯示的畫面。
和 應該是在使用其他元件。
這種看起來像 HTML、卻可以寫在 JavaScript 裡面的語法,好像就是 React 常看到的 JSX。
而因為這個專案還使用了 TypeScript,所以副檔名才會是.tsx。
至於 JSX 和 TSX 這兩者是什麼東東,或是有什麼差別就留著後面再另外研究了解一下當作回家作業
接著我打開原本猜測是進入點的 main.tsx,看到了類似下面的程式碼:
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
這一段對第一次接觸 React 的我來說,幾乎每一行都有問題。createRoot 是建立什麼?document.getElementById('root') 看起來是在尋找 HTML 裡面某個 id="root" 的元素。
後面的驚嘆號 ! 又是什麼?render 應該和「把畫面顯示出來」有關?StrictMode 又是必要的嗎?
現在的我目前只能猜測 main.tsx 是整個網頁的進入點而已。
再看到 App.tsx,可以看到它引入了其他檔案:import TodoForm from './components/TodoForm'import TodoList from './components/TodoList'
這讓我想到以前在 Vue 裡面引入元件的方式。語法雖然不完全相同,但概念似乎都是先把元件拆成不同檔案,再由上層元件把它們組合起來。
依照目前看到的結構,我暫時把它理解成:
main.tsx
└─ App.tsx
├─ TodoForm.tsx
└─ TodoList.tsx
└─ TodoItem.tsx
App.tsx 負責組合主要畫面,TodoForm.tsx 負責新增待辦事項,TodoList.tsx 負責顯示清單,而 TodoItem.tsx 則負責顯示清單中的單筆資料。
另外,我發現雖然 React 沒有.vue 檔,也沒有明確分開的 和 ,但「把畫面拆成多個元件」的想法其實沒有想像中陌生。所以陌生的也或許是寫法的關係吧,不一定是觀念。
繼續往下看,我開始遇到更多熟悉又陌生的程式碼:const [todos, setTodos] = useState<Todo[]>([])
其中有一些部分可以靠名稱猜測:todos 應該是目前的待辦事項資料。setTodos 可能是修改待辦事項用的東西。useState 看起來和 Vue 的 ref() 有點像。Todo[] 應該表示這份資料裡面會放很多筆 Todo。
最後的 [] 應該是初始值,代表一開始沒有任何待辦事項。
但是相反的也有更多我有看沒有懂的東西出現。
為什麼修改資料不能直接寫 todos.push(...)?
為什麼需要另外使用 setTodos?useState<Todo[]> 中間的尖括號是什麼?
資料改變之後,React 又是怎麼知道畫面需要重新顯示的?
這些問題我也預計會留到之後再逐一驗證確認。
Vue 裡熟悉的功能,在 React 裡換了名字?
在 Todo List 的程式碼裡,我也看到不少可以和 Vue 對照的地方。
例如 Vue 可能會使用 v-for 顯示清單,但 React 裡似乎是直接使用 JavaScript 的 map():
todos.map((todo) => (
<TodoItem key={todo.id} todo={todo} />
))
Vue 使用 v-if 控制元素是否出現,React 則可能直接寫 JavaScript 的條件判斷:{todos.length === 0 && <p>目前沒有待辦事項</p>}
Vue 使用 @click 綁定點擊事件,React 則寫成:<button onClick={handleDelete}>刪除</button>
乍看之下,好像只是把 Vue 的功能換成另一套名稱;但再仔細看,又會發現 React 更常直接使用 JavaScript 本身的語法。
把整個專案大概看過一次後,目前大致可以理解:
專案被拆成數個 Component。
main.tsx 應該負責啟動 React。App.tsx 負責組合主要畫面及部分資料。TodoForm 負責輸入與新增資料。TodoList 負責產生待辦清單。TodoItem 負責顯示每一筆待辦事項。目前仍然處於看得到、猜得到一點,卻還無法完整說明的狀態,簡單說現在看懂的比較像是「這段程式碼可能想做什麼」,而不是「我知道它為什麼能這樣運作」。
雖然這次我直接請AI生成一個小小專案,但刻意沒有一遇到不懂的地方就立刻問 AI,而是先靠檔名、變數名稱,以及過去寫 Vue 的經驗去猜測程式碼的用途。儘管這些猜測一定不完全正確,但我個人認為它們仍可以成為後續學習的起點。
接下來幾天當然就是一步一步確認跟理解,或許學完之後再回頭看這一篇,會發現現在有不少想法其實猜錯了。不過這也正是我想記錄的部分:不是只留下最後查到的正確答案,也留下自己從「看不懂」到「慢慢理解」的過程!